#include "TaskQueue.h"

TaskQueue::TaskQueue(size_t capacity)
    :_capacity(capacity)
    ,_taskQue()
    ,_mutex()
    ,_notFull()
    ,_notEmpty()
     ,_flag(true)
{

}

TaskQueue::~TaskQueue(){

}

void TaskQueue::push(ElemType && taskcb){
    //01 加锁
    unique_lock<mutex> ul(_mutex);
    //02 判断满
    while(full()){
        //满了就让生产者wait
        _notFull.wait(ul);
    }
    //   不满就push + 唤醒消费者
    _taskQue.push(std::move(taskcb));
    _notEmpty.notify_one();
}

ElemType TaskQueue::pop(){
    unique_lock<mutex> ul(_mutex);

    //由于Q2，需要唤醒子线程，但是该条件empty()始终为true
    while(empty() && _flag){
        _notEmpty.wait(ul);
    }

    if(_flag){
        ElemType task = _taskQue.front();
        _taskQue.pop();

        _notFull.notify_one();
        return task;
    }else{
        return nullptr;
    }
}

bool TaskQueue:: full() const{
    return _taskQue.size() == _capacity;
}

bool TaskQueue::empty() const{
    return 0 == _taskQue.size();
}

void TaskQueue::wakeup(){
    _flag = false;
    _notEmpty.notify_all();
}

